package br.requisiteworks.requisito.modelo.dao.jpa;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceException;
import javax.persistence.TypedQuery;

import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import br.requisiteworks.requisito.modelo.TipoRequisito;
import br.requisiteworks.requisito.modelo.dao.TipoRequisitoDao;
import br.requisiteworks.util.persistencia.ErroBancoDados;
import br.requisiteworks.util.persistencia.ResultadoVazio;

@Repository
public class JpaTipoRequisitoDao implements TipoRequisitoDao {

	@PersistenceContext
	private EntityManager entityManager;

	@Override
	@Transactional
	public TipoRequisito select(int numero) throws ResultadoVazio {
		TypedQuery<TipoRequisito> query = this.entityManager.createQuery(
				"SELECT tr FROM TipoRequisito tr WHERE tr.numero=:numero",
				TipoRequisito.class);

		query.setParameter("numero", numero);

		try {
			TipoRequisito tipo = query.getSingleResult();

			tipo.getAtributos().size();

			return tipo;
		} catch (NoResultException e) {
			throw new ResultadoVazio(
					"Nao foi encontrado tipo de requisito com numero = "
							+ numero);
		}
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public void delete(TipoRequisito entidate) throws ErroBancoDados {
		try {
			entidate.setRegistroAtivo(false);
			this.update(entidate);
		} catch (PersistenceException e) {
			throw new ErroBancoDados("Ocorreu um erro ao deletar requisito: "
					+ entidate, e);
		}
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public void insert(TipoRequisito entidate) throws ErroBancoDados {
		entityManager.persist(entidate);
	}

	@Override
	@Transactional
	public List<TipoRequisito> select() throws ResultadoVazio {

		TypedQuery<TipoRequisito> listTipos = this.entityManager.createQuery(
				"SELECT tp FROM TipoRequisito tp WHERE tp.registroAtivo=true",
				TipoRequisito.class);

		List<TipoRequisito> tipos = listTipos.getResultList();

		ResultadoVazio
				.verificaVazio(tipos,
						"Nao foi encontrado nenhum registro de tipo de requisito ativo");

		for (TipoRequisito tipo : tipos) {
			tipo.getAtributos().size();
		}

		return tipos;
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public void update(TipoRequisito entidate) throws ErroBancoDados {
		try {
			entityManager.merge(entidate);
			entityManager.flush();
		} catch (PersistenceException e) {
			throw new ErroBancoDados("Ocorreu um erro ao atualizar requisito: "
					+ entidate, e);
		}
	}

}
